from typing import Dict, Optional

from redis.asyncio import ConnectionPool, Redis

from app.core.config import settings


class RedisHelper:
    """一个全局单例的Redis连接管理器"""

    _instance: Optional["RedisHelper"] = None
    _redis_connections: Dict[int, Redis] = {}
    _connection_pools: Dict[int, ConnectionPool] = {}

    def __new__(cls, *args, **kwargs):
        if not cls._instance:
            cls._instance = super().__new__(cls)
        return cls._instance

    def __init__(self):
        self.host: str = settings.REDIS_HOST
        self.port: int = settings.REDIS_PORT
        self.password: str = settings.REDIS_PASSWORD
        self.max_connections: int = 10

    def get_pool(self, db: int) -> ConnectionPool:
        """获取指定数据库的连接池"""
        if db not in self._connection_pools:
            pool = ConnectionPool(
                host=self.host,
                port=self.port,
                password=self.password,
                db=db,
                max_connections=self.max_connections,
                decode_responses=True,
                encoding="utf8",
                health_check_interval=30,
                retry_on_timeout=True,
                socket_keepalive=True,
            )
            self._connection_pools[db] = pool
        return self._connection_pools[db]

    def get_connection(self, db: int) -> Redis:
        """获取指定数据库的Redis连接"""
        if db not in self._redis_connections:
            pool = self.get_pool(db)
            redis = Redis(connection_pool=pool, decode_responses=True)
            self._redis_connections[db] = redis
        return self._redis_connections[db]

    @property
    def redis(self) -> Redis:
        """获取默认数据库的Redis连接"""
        return self.get_connection(settings.DEFAULT_REDIS_DB)

    async def close(self):
        """关闭所有Redis连接和连接池"""
        # 关闭所有Redis连接
        for redis in self._redis_connections.values():
            await redis.close()
        self._redis_connections.clear()

        # 关闭所有连接池
        for pool in self._connection_pools.values():
            await pool.disconnect()
        self._connection_pools.clear()


# 创建全局Redis助手实例
redis_helper = RedisHelper()

# 创建默认Redis连接实例，支持直接调用Redis方法
redis_conn = redis_helper.redis
